﻿using CoreWCF;
using SlamDunk.MES.AppService.Maps;
using SlamDunk.MES.Domain.Mediators;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.ReportView.Models;
using SlamDunk.ValueObjects.Enums;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SlamDunk.MES.AppService.Implements
{
    /// <summary>
    /// 报表统计服务契约实现
    /// </summary>
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IncludeExceptionDetailInFaults = true)]
    public class ReportContract : IReportContract
    {
        #region # 字段及构造器

        /// <summary>
        /// 仓储中介者
        /// </summary>
        private readonly RepositoryMediator _repMediator;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public ReportContract(RepositoryMediator repMediator)
        {
            this._repMediator = repMediator;
        }

        #endregion

        #region # 获取作业计划物料出/入库概要列表 —— IEnumerable<MaterialSummaryInfo> GetExecutionPlanMaterialBoundSummaries(...
        /// <summary>
        /// 获取作业计划物料出/入库概要列表
        /// </summary>
        /// <param name="executionPlanId">作业计划Id</param>
        /// <param name="directionType">出/入库类型</param>
        /// <returns>物料出/入库概要列表</returns>
        public IEnumerable<MaterialSummaryInfo> GetExecutionPlanMaterialBoundSummaries(Guid executionPlanId, StockDirectionType directionType)
        {
            ICollection<MaterialSummaryInfo> materialSummaries = this._repMediator.BoundRecordRep.GetMaterialSummariesByExecutionPlan(executionPlanId, directionType);

            //保质期TimeSpan处理
            foreach (MaterialSummaryInfo materialSummary in materialSummaries)
            {
                materialSummary.GuaranteePeriod = materialSummary.GuaranteePeriodTicks.HasValue
                    ? TimeSpan.FromTicks(materialSummary.GuaranteePeriodTicks.Value)
                    : (TimeSpan?)null;
            }

            return materialSummaries;
        }
        #endregion

        #region # 获取作业计划人员使用概要列表 —— IEnumerable<PersonSummaryInfo> GetExecutionPlanPersonUseSummaries(...
        /// <summary>
        /// 获取作业计划人员使用概要列表
        /// </summary>
        /// <param name="executionPlanId">作业计划Id</param>
        /// <returns>人员使用概要列表</returns>
        public IEnumerable<PersonSummaryInfo> GetExecutionPlanPersonUseSummaries(Guid executionPlanId)
        {
            return this._repMediator.WorkOrderActualPersonRep.GetPersonSummariesByExecutionPlan(executionPlanId);
        }
        #endregion

        #region # 获取作业计划设备使用概要列表 —— IEnumerable<EquipmentSummaryInfo> GetExecutionPlanEquipmentUseSummaries(...
        /// <summary>
        /// 获取作业计划设备使用概要列表
        /// </summary>
        /// <param name="executionPlanId">作业计划Id</param>
        /// <returns>设备使用概要列表</returns>
        public IEnumerable<EquipmentSummaryInfo> GetExecutionPlanEquipmentUseSummaries(Guid executionPlanId)
        {
            return this._repMediator.WorkOrderActualEquipmentRep.GetEquipmentSummariesByExecutionPlan(executionPlanId);
        }
        #endregion

        #region # 获取作业计划物料使用概要列表 —— IEnumerable<MaterialSummaryInfo> GetExecutionPlanMaterialUseSummaries(...
        /// <summary>
        /// 获取作业计划物料使用概要列表
        /// </summary>
        /// <param name="executionPlanId">作业计划Id</param>
        /// <param name="directionType">物料输入/输出类型</param>
        /// <returns>物料使用概要列表</returns>
        public IEnumerable<MaterialSummaryInfo> GetExecutionPlanMaterialUseSummaries(Guid executionPlanId, MaterialDirectionType directionType)
        {
            ICollection<MaterialSummaryInfo> materialSummaries = this._repMediator.WorkOrderActualMaterialRep.GetMaterialSummariesByExecutionPlan(executionPlanId, directionType);

            //保质期TimeSpan处理
            foreach (MaterialSummaryInfo materialSummary in materialSummaries)
            {
                materialSummary.GuaranteePeriod = materialSummary.GuaranteePeriodTicks.HasValue
                    ? TimeSpan.FromTicks(materialSummary.GuaranteePeriodTicks.Value)
                    : (TimeSpan?)null;
            }

            return materialSummaries;
        }
        #endregion

        #region # 获取产品合格率字典 —— IDictionary<MaterialInfo, decimal> GetProductQualifiedRates(DateTime inspectedDate)
        /// <summary>
        /// 获取产品合格率字典
        /// </summary>
        /// <param name="inspectedDate">质检日期</param>
        /// <returns>产品合格率字典</returns>
        public IDictionary<MaterialInfo, decimal> GetProductQualifiedRates(DateTime inspectedDate)
        {
            IDictionary<Guid, decimal> dictionary = this._repMediator.QualityInspectionRep.GetProductQualifiedRates(inspectedDate);
            IDictionary<Guid, MaterialInfo> materialInfos = this._repMediator.MaterialRep.Find(dictionary.Keys).ToDictionary(x => x.Key, x => x.Value.ToDTO(null));
            IDictionary<MaterialInfo, decimal> result = dictionary.ToDictionary(x => materialInfos[x.Key], x => x.Value);

            return result;
        }
        #endregion

        #region # 获取物料投入周期概要字典 —— {DateTime, MaterialQuantityInfo[]} GetMaterialInputPeriodicSummaries(...
        /// <summary>
        /// 获取物料投入周期概要字典
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>物料投入周期概要字典</returns>
        /// <remarks>
        /// 键：日期，值：物料数量列表
        /// </remarks>
        public IDictionary<DateTime, MaterialQuantityInfo[]> GetMaterialInputPeriodicSummaries(DateTime startTime, DateTime endTime)
        {
            return this._repMediator.WorkOrderActualMaterialRep.GetMaterialInputPeriodicSummaries(startTime, endTime);
        }
        #endregion

        #region # 获取产品产出周期概要字典 —— {DateTime, ProductQuantityInfo[]} GetProductOutputPeriodicSummaries(...
        /// <summary>
        /// 获取产品产出周期概要字典
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>产品产出周期概要字典</returns>
        /// <remarks>
        /// 键：日期，值：产品数量列表
        /// </remarks>
        public IDictionary<DateTime, ProductQuantityInfo[]> GetProductOutputPeriodicSummaries(DateTime startTime, DateTime endTime)
        {
            return this._repMediator.QualityInspectionRep.GetProductOutputPeriodicSummaries(startTime, endTime);
        }
        #endregion

        #region # 获取作业计划状态/数量字典 —— IDictionary<ExecutionPlanStatus, int> GetExecutionPlanStatusCounts(...
        /// <summary>
        /// 获取作业计划状态/数量字典
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>作业计划状态/数量字典</returns>
        public IDictionary<ExecutionPlanStatus, int> GetExecutionPlanStatusCounts(DateTime startTime, DateTime endTime)
        {
            return this._repMediator.ExecutionPlanRep.GetExecutionPlanStatusCounts(startTime, endTime);
        }
        #endregion

        #region # 获取产品数量列表 —— IEnumerable<ProductQuantityInfo> GetProductQuantities(DateTime startTime...
        /// <summary>
        /// 获取产品数量列表
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>产品数量列表</returns>
        public IEnumerable<ProductQuantityInfo> GetProductQuantities(DateTime startTime, DateTime endTime)
        {
            return this._repMediator.QualityInspectionRep.GetProductQuantities(startTime, endTime);
        }
        #endregion
    }
}
